/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file           : main.c
 * @brief          : Main program body
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2024 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "tim.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define	ON	0
#define OFF	1
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
//共阳数码管编码表
uint8_t table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
		//			  0		1	 2	  3	   4	5	 6	  7	   8
		0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0xff};
//	  9	   A	B	 C	  D	   E	F	 -	全灭


uint8_t	seconds = 0;	//倒计时秒数
uint8_t counter = 0;	//0.5秒计数
uint8_t flag	= 0;	//1秒计时到的标志
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
 * @brief  The application entry point.
 * @retval int
 */
int main(void)
{

	/* USER CODE BEGIN 1 */

	/* USER CODE END 1 */

	/* MCU Configuration--------------------------------------------------------*/

	/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
	HAL_Init();

	/* USER CODE BEGIN Init */

	/* USER CODE END Init */

	/* Configure the system clock */
	SystemClock_Config();

	/* USER CODE BEGIN SysInit */

	/* USER CODE END SysInit */

	/* Initialize all configured peripherals */
	MX_GPIO_Init();
	MX_TIM3_Init();
	/* USER CODE BEGIN 2 */
	HAL_TIM_Base_Start_IT(&htim3);
	/* USER CODE END 2 */

	/* Infinite loop */
	/* USER CODE BEGIN WHILE */
	while (1)
	{
		/*设计一个具有2位倒计时显示的十字路口交通灯系统。东西向直行12秒，左转8秒，
		 * 黄灯3秒；南北向直行11秒，左转6秒，黄灯3秒，数码管显示北向红、黄、绿灯
		 * 的时间。
		 */
		Display(seconds);
		switch (counter) {
		case 0:		//东西直行12秒
			seconds = 12;
			HAL_GPIO_WritePin(EW_GREEN_F_GPIO_Port, EW_GREEN_F_Pin, ON);
			HAL_GPIO_WritePin(SN_RED_GPIO_Port, SN_RED_Pin, ON);
			HAL_GPIO_WritePin(EW_RED_GPIO_Port, EW_RED_Pin | EW_YELLOW_Pin
					| EW_GREEN_L_Pin | SN_YELLOW_Pin | SN_GREEN_F_Pin |
					SN_GREEN_L_Pin, OFF);
			break;
		case 24:	//东西黄灯闪3 秒
			seconds = 3;
			HAL_GPIO_WritePin(EW_GREEN_F_GPIO_Port, EW_GREEN_F_Pin, OFF);
			HAL_GPIO_WritePin(EW_YELLOW_GPIO_Port, EW_YELLOW_Pin, ON);
			break;
		case 25:
			HAL_GPIO_WritePin(EW_YELLOW_GPIO_Port, EW_YELLOW_Pin, OFF);break;
		case 26:
			HAL_GPIO_WritePin(EW_YELLOW_GPIO_Port, EW_YELLOW_Pin, ON);break;
		case 27:
			HAL_GPIO_WritePin(EW_YELLOW_GPIO_Port, EW_YELLOW_Pin, OFF);break;
		case 28:
			HAL_GPIO_WritePin(EW_YELLOW_GPIO_Port, EW_YELLOW_Pin, ON);break;
		case 29:
			HAL_GPIO_WritePin(EW_YELLOW_GPIO_Port, EW_YELLOW_Pin, OFF);break;
		case 30:	//东西左转8 秒
			seconds = 8;
			HAL_GPIO_WritePin(EW_YELLOW_GPIO_Port, EW_YELLOW_Pin, OFF);
			HAL_GPIO_WritePin(EW_GREEN_L_GPIO_Port, EW_GREEN_L_Pin, ON);
			break;
		case 46:	//东西黄灯闪 3秒
			seconds =  3;
			HAL_GPIO_WritePin(EW_GREEN_L_GPIO_Port, EW_GREEN_L_Pin, OFF);
			HAL_GPIO_WritePin(EW_YELLOW_GPIO_Port, EW_YELLOW_Pin, ON);
			break;
		case 47:
			HAL_GPIO_WritePin(EW_YELLOW_GPIO_Port, EW_YELLOW_Pin, OFF);break;
		case 48:
			HAL_GPIO_WritePin(EW_YELLOW_GPIO_Port, EW_YELLOW_Pin, ON);break;
		case 49:
			HAL_GPIO_WritePin(EW_YELLOW_GPIO_Port, EW_YELLOW_Pin, OFF);break;
		case 50:
			HAL_GPIO_WritePin(EW_YELLOW_GPIO_Port, EW_YELLOW_Pin, ON);break;
		case 51:
			HAL_GPIO_WritePin(EW_YELLOW_GPIO_Port, EW_YELLOW_Pin, OFF);break;
		case 52:	//南北直行11秒
			seconds = 11;
			HAL_GPIO_WritePin(EW_RED_GPIO_Port, EW_RED_Pin, ON);
			HAL_GPIO_WritePin(SN_RED_GPIO_Port, SN_RED_Pin, OFF);
			HAL_GPIO_WritePin(SN_GREEN_F_GPIO_Port, SN_GREEN_F_Pin, ON);
			break;
		case 74:	//南北黄灯闪3 秒
			seconds = 3;
			HAL_GPIO_WritePin(SN_GREEN_F_GPIO_Port, SN_GREEN_F_Pin, OFF);
			HAL_GPIO_WritePin(SN_YELLOW_GPIO_Port, SN_YELLOW_Pin, ON);break;
		case 75:
			HAL_GPIO_WritePin(SN_YELLOW_GPIO_Port, SN_YELLOW_Pin, OFF);break;
		case 76:
			HAL_GPIO_WritePin(SN_YELLOW_GPIO_Port, SN_YELLOW_Pin, ON);break;
		case 77:
			HAL_GPIO_WritePin(SN_YELLOW_GPIO_Port, SN_YELLOW_Pin, OFF);break;
		case 78:
			HAL_GPIO_WritePin(SN_YELLOW_GPIO_Port, SN_YELLOW_Pin, ON);break;
		case 79:
			HAL_GPIO_WritePin(SN_YELLOW_GPIO_Port, SN_YELLOW_Pin, OFF);break;
		case 80:	//南北左转6 秒
			seconds = 6;
			HAL_GPIO_WritePin(SN_GREEN_L_GPIO_Port, SN_GREEN_L_Pin, ON);break;
		case 92:	//南北黄灯闪3 秒
			seconds = 3;
			HAL_GPIO_WritePin(SN_GREEN_L_GPIO_Port, SN_GREEN_L_Pin, OFF);
			HAL_GPIO_WritePin(SN_YELLOW_GPIO_Port, SN_YELLOW_Pin, ON);break;
		case 93:
			HAL_GPIO_WritePin(SN_YELLOW_GPIO_Port, SN_YELLOW_Pin, OFF);break;
		case 94:
			HAL_GPIO_WritePin(SN_YELLOW_GPIO_Port, SN_YELLOW_Pin, ON);break;
		case 95:
			HAL_GPIO_WritePin(SN_YELLOW_GPIO_Port, SN_YELLOW_Pin, OFF);break;
		case 96:
			HAL_GPIO_WritePin(SN_YELLOW_GPIO_Port, SN_YELLOW_Pin, ON);break;
		case 97:
			HAL_GPIO_WritePin(SN_YELLOW_GPIO_Port, SN_YELLOW_Pin, OFF);break;
		default:
			break;
		}
		/* USER CODE END WHILE */

		/* USER CODE BEGIN 3 */
	}
	/* USER CODE END 3 */
}

/**
 * @brief System Clock Configuration
 * @retval None
 */
void SystemClock_Config(void)
{
	RCC_OscInitTypeDef RCC_OscInitStruct = {0};
	RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

	/** Initializes the RCC Oscillators according to the specified parameters
	 * in the RCC_OscInitTypeDef structure.
	 */
	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
	RCC_OscInitStruct.HSEState = RCC_HSE_ON;
	RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
	RCC_OscInitStruct.HSIState = RCC_HSI_ON;
	RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
	RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
	RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL2;
	if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
	{
		Error_Handler();
	}
	/** Initializes the CPU, AHB and APB buses clocks
	 */
	RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
			|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
	RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
	RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
	RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
	RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

	if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
	{
		Error_Handler();
	}
}

/* USER CODE BEGIN 4 */
/*
 * 功能：2 位数码管显示（共阳）
 * 参数：digital, 显示的数值
 * 返回值：无
 */
void Display(uint8_t digital)
{
	uint8_t x1,x10;	//个位，十位
	x1 = digital % 10;
	x10= digital / 10;

	SEGA_GPIO_Port->ODR = table[x10];	//高位为0，导致位码清0。先送段码，再送位码。
	HAL_GPIO_WritePin(SEL1_GPIO_Port, SEL1_Pin, 1);
	HAL_GPIO_WritePin(SEL2_GPIO_Port, SEL2_Pin, 0);
	HAL_Delay(10);
	SEGA_GPIO_Port->ODR = table[17];	//消影

	SEGA_GPIO_Port->ODR = (uint32_t)table[x1]+0x00020000;
	HAL_GPIO_WritePin(SEL1_GPIO_Port, SEL1_Pin, 0);
	HAL_GPIO_WritePin(SEL2_GPIO_Port, SEL2_Pin, 1);
	HAL_Delay(10);
	SEGA_GPIO_Port->ODR = table[17];	//消影
}

/*
 * 定时中断回调函数
 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	/* Prevent unused argument(s) compilation warning */
	UNUSED(htim);
	if(htim == &htim3)
	{
		if(counter > 97)
			counter = 0;
		else
			counter++;
		if(flag > 0)
			flag = 0;
		else
			flag++;
		if(flag == 0)
		{
			if(seconds > 0)
				seconds--;
		}
	}
	/* NOTE : This function should not be modified, when the callback is needed,
            the HAL_TIM_PeriodElapsedCallback could be implemented in the user file
	 */
}
/* USER CODE END 4 */

/**
 * @brief  This function is executed in case of error occurrence.
 * @retval None
 */
void Error_Handler(void)
{
	/* USER CODE BEGIN Error_Handler_Debug */
	/* User can add his own implementation to report the HAL error return state */
	__disable_irq();
	while (1)
	{
	}
	/* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
 * @brief  Reports the name of the source file and the source line number
 *         where the assert_param error has occurred.
 * @param  file: pointer to the source file name
 * @param  line: assert_param error line source number
 * @retval None
 */
void assert_failed(uint8_t *file, uint32_t line)
{
	/* USER CODE BEGIN 6 */
	/* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
	/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
